package zpengblog.taskdemo.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import zpengblog.taskdemo.aop.custom.TaskRedisLock;
import zpengblog.taskdemo.util.RedisLockUtils;

import java.lang.reflect.Method;

/**
 * 定时任务锁切面，对加了自定义redis锁注解的任务进行拦截.
 *
 * @author linzp
 * @version 1.0.0
 * CreateDate 2021/1/14 16:59
 */
@Component
@Aspect
@Slf4j
public class RedisLockAspect {

    @Autowired
    private RedisLockUtils redisLockUtils;

    /**
     * 拦截自定义的redis锁注解.
     */
    @Pointcut("@annotation(zpengblog.taskdemo.aop.custom.TaskRedisLock)")
    public void pointCut(){}

    /**
     * 环绕通知.
     */
    @Around("pointCut()")
    public Object Around(ProceedingJoinPoint pjp) throws Throwable {
        //获取方法
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        Method method = methodSignature.getMethod();
        //获取方法上的注解
        TaskRedisLock annotation = method.getAnnotation(TaskRedisLock.class);
        //获取任务名称
        String taskName = annotation.taskName();
        //获取失效时间
        long expireTime = annotation.expireTime();
        log.info("加锁>>>当前线程id：[{}]", Thread.currentThread().getId());
        try {
            //获取锁
            Boolean lock = redisLockUtils.getLock(taskName, expireTime);
            if (lock) {
                return pjp.proceed();
            }else {
                log.error("[{} 任务] 获取redis锁失败了，此次不执行...", taskName);
            }
        }catch (Exception e){
            log.error("[{} 任务]获取锁异常了！", taskName, e);
        }finally {
            log.info("释放>>>当前线程id：[{}]", Thread.currentThread().getId());
            redisLockUtils.delLock(taskName);
        }
        return null;
    }
}
